補充 Kotlin & Flutter 堆疊排列元件實例
需修改兩個layout檔案
使用 FrameLayout
layout_height 會影響可以堆疊元件的範圍。
FrameLayout 裡層的元件可透過 layout_gravity 設定堆疊位置。| 實際執行結果 | 
|---|
activity_main.xml 內容:<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <TextView
        android:id="@+id/TitleTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="FrameLayout"
        android:textColor="@color/black"
        android:textSize="20dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <FrameLayout
        android:id="@+id/FrameLayout"
        android:layout_width="match_parent"
        android:layout_height="500dp"
        android:background="@color/lightGreen"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:paddingStart="5dp"
        android:paddingEnd="5dp"
        app:layout_constraintTop_toBottomOf="@id/TitleTV"
        app:layout_constraintBottom_toBottomOf="parent"
        >
        <include
            layout="@layout/card_item"
            android:layout_width="140dp"
            android:layout_height="170dp"
            android:layout_gravity="right" />
        <include
            layout="@layout/card_item"
            android:layout_width="140dp"
            android:layout_height="170dp"
            android:layout_gravity="center" />
        <include
            layout="@layout/card_item"
            android:layout_width="140dp"
            android:layout_height="170dp"
            android:layout_gravity="left|bottom" />
        <include
            layout="@layout/card_item"
            android:layout_width="140dp"
            android:layout_height="170dp"
            android:layout_gravity="right|bottom" />
        <include layout="@layout/card_item" />
    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
card_item.xml 內容:主要是建立書籍圖片的 card Item。<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:cardBackgroundColor="@color/white"
    app:cardCornerRadius="10dp"
    app:contentPadding="5dp"
    android:layout_margin="10dp">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/textView"
            android:text="My book"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:textColor= "@color/black"
            android:textSize="20dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="120dp"
            android:layout_height="80dp"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/textView"
            app:srcCompat="@drawable/image_book" />
        <ImageView
            android:id="@+id/imageViewButton"
            android:layout_width="45dp"
            android:layout_height="45dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/imageView"
            app:srcCompat="@drawable/star"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
需修改一個檔案
使用 Stack 元件
Stack 裡層的子元件可透過 Positioned 元件設定堆疊位置。| 實際執行結果 | 
|---|
main.dart 檔案內容:import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatefulWidget {
  const MyApp({super.key});
  @override
  _MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<StatefulWidget> {
  ///是否點擊收藏按鈕
  bool bIsCollectBook = false;
  @override
  Widget build(BuildContext context) {
    ///由上到下垂直排列元件 list
    List<Widget> _widgetList = [
      _wTitle("My book"),
      _wBookImage("asset/image_book.jpg"),
      _wButtonForCollectBook(bIsCollect: bIsCollectBook)
    ];
    ///圓角框元件內容
    Widget _wCardContent = Container(
        padding: EdgeInsets.symmetric(vertical: 5,horizontal: 3),
        constraints: BoxConstraints(maxWidth: 120),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: _widgetList,
        ));
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            appBar: _wAppBar(),
            body: Container(
              alignment: Alignment.center,
              color: Colors.lightGreen.withOpacity(0.5),
              child: Stack(children: [
                Positioned(left: 28, child: _wCardItem(_wCardContent)),
                Container(color: Colors.transparent,height: 650,),
                Positioned(
                  child: _wCardItem(_wCardContent),
                  right: 28,
                ),
                Positioned(
                  child: _wCardItem(_wCardContent),
                  right: 28,
                  bottom: 18,
                ),
                Positioned(
                  child: _wCardItem(_wCardContent),
                  left: 28,
                  bottom: 18,
                ),
                Positioned(
                  child: _wCardItem(_wCardContent),
                  right: 140,
                  top: 200,
                ),
              ]),
            )));
  }
  PreferredSizeWidget _wAppBar(){
    return AppBar(
      backgroundColor: Colors.white,
      centerTitle: true,
      title: Text("Stack",style: TextStyle(color:Colors.black,fontSize: 30,letterSpacing: 2,decoration: TextDecoration.underline),),
      elevation: 0,
    );
  }
  Widget _wCardItem(Widget wItem){
    return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
      child: wItem,
    );
  }
  
  ///標題元件
  Widget _wTitle(String sTitle){
    return Text(
      "$sTitle",
      style: TextStyle(fontSize: 18,fontWeight: FontWeight.w500),
      textAlign: TextAlign.start,
    );
  }
  ///書籍圖片元件
  Widget _wBookImage(String sImagePath){
    return Container(
      alignment: Alignment.center,
      padding: EdgeInsets.symmetric(horizontal: 10,vertical: 10),
      child: Image.asset(
        "$sImagePath",
        height: 120,
        width: 80,
      ),
    );
  }
  ///收藏書籍按鈕元件
  Widget _wButtonForCollectBook({bool bIsCollect = false}){
    String sImagePath = bIsCollect ? "asset/star_select.png":"asset/star_unselect.png";
    return Container(
      alignment: Alignment.center,
      child: InkWell(
          onTap: () {
            ///點擊收藏書籍按鈕, 改變按鈕狀態 flag , 進而改變按鈕顏色
            setState(() {
              bIsCollectBook = !bIsCollectBook;
            });
          },
          child: Image.asset(
            "$sImagePath",
            height: 45,
            width: 45,
          )),
    );
  }
}